from loguru import logger
from datetime import datetime
from fastapi import APIRouter, Depends, HTTPException, Query, Body, status
from sqlalchemy.orm import Session, joinedload
from typing import Optional, Union
from app.db.session import get_db
from app.db.models.user import Apply, Friend, FriendGroup, Group, User
from app.schemas.user import (
    ApplyReviewRequest
)
from app.utils.security import get_current_user
from app.services.user import UserService

router = APIRouter()


# ------------------------- 申请相关接口 -------------------------
@router.post("/apply/friend", tags=["申请管理"], status_code=status.HTTP_201_CREATED)
async def apply_friend(
        data: dict = Body(..., example={
            "targetUserId": "uuid-xxx-xxx",  # 改为业务ID
            "remark": "",
            "groupingId": 509,
            "content": "我是666ren，想添加你为好友！"
        }),
        db: Session = Depends(get_db),
        current_user: User = Depends(get_current_user)
):
    """发送好友申请（完全匹配前端参数）"""
    # 参数验证
    if not data.get("targetUserId"):
        return {"code": 400, "message": "无效的目标用户ID", "data": None}
        
    # 检查目标用户是否存在
    target_user = UserService.get_user_by_userid(db, data["targetUserId"])
    if not target_user:
        return {"code": 404, "message": "目标用户不存在", "data": None}
        
    # 检查是否是自己申请自己
    if target_user.id == current_user.id:
        return {"code": 4002, "message": "不能添加自己为好友", "data": None}

    # 检查是否已经是好友（双向检查）
    existing_friend = db.query(Friend).filter(
        Friend.user_id == current_user.id,
        Friend.friend_id == target_user.id,
        Friend.status == 1
    ).first()
    
    reverse_friend = db.query(Friend).filter(
        Friend.user_id == target_user.id,
        Friend.friend_id == current_user.id,
        Friend.status == 1
    ).first()
    
    if existing_friend or reverse_friend:
        return {"code": 4003, "message": "对方已经是你的好友", "data": None}

    # 检查重复申请
    exists = db.query(Apply).filter(
        Apply.applicant_id == current_user.id,
        Apply.target_id == target_user.id,
        Apply.status == 0
    ).first()
    if exists:
        return {"code": 4001, "message": "请勿重复提交申请", "data": None}

    apply = Apply(
        applicant_id=current_user.id,
        target_id=target_user.id,
        content=data.get("content", ""),
        type=0,
        status=0
    )
    db.add(apply)
    db.commit()
    db.refresh(apply)
    
    # 通过WebSocket通知目标用户
    try:
        from app.api.ws import ws_handler
        
        if target_user.id in ws_handler.active_connections:
            # 构建通知消息
            notification = {
                "type": 3,  # 好友申请
                "body": {
                    "id": apply.id,
                    "userId": current_user.id,
                    "content": data.get("content", ""),
                    "type": 0,
                    "targetId": target_user.id,
                    "status": 0,
                    "createdAt": apply.created_at.strftime("%Y-%m-%d %H:%M:%S") if apply.created_at else datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
                    "user": {
                        "id": current_user.id,
                        "nickname": current_user.nickname,
                        "sex": current_user.sex or 0,
                        "online": 1 if current_user.online else 0
                    }
                }
            }
            await ws_handler.send_message(target_user.id, notification)
    except Exception as e:
        # 记录错误但不中断流程
        logger.error(f"WebSocket通知好友申请失败: {str(e)}")
    
    return {"code": 0, "message": "成功！", "data": apply.id}


@router.post("/apply/friend/review", tags=["申请管理"])
async def review_friend_apply(
        data: ApplyReviewRequest,
        db: Session = Depends(get_db),
        current_user: User = Depends(get_current_user)
):
    """审核好友申请（参数映射示例）"""
    apply = db.query(Apply).filter(
        Apply.id == data.id,
        Apply.target_id == current_user.id,
        Apply.status == 0
    ).first()
    if not apply:
        return {"code": 404, "message": "申请不存在/被处理", "data": None}

    if data.status == 1:  # 同意申请
        # 验证分组是否存在
        group = db.query(FriendGroup).filter(
            FriendGroup.user_id == current_user.id,
            FriendGroup.id == data.groupingId
        ).first()
        if not group:
            return {"code": 400, "message": "无效的分组", "data": None}

        # 创建双向好友关系
        try:
            existing_friend = db.query(Friend).filter(
                Friend.user_id == current_user.id,
                Friend.friend_id == apply.applicant_id
            ).first()
            if existing_friend:
                # 如果之前被删除/拉黑，直接恢复
                existing_friend.status = 1
                existing_friend.friend_group_id = group.id
                existing_friend.remark = data.remark or existing_friend.remark
            else:
                db.add(Friend(
                    user_id=current_user.id,
                    friend_id=apply.applicant_id,
                    friend_group_id=group.id,
                    status=1
                ))

            # 为申请者添加好友（使用默认分组）
            applicant_default_group = db.query(FriendGroup).join(Group).filter(
                FriendGroup.user_id == apply.applicant_id,
                Group.is_default == True
            ).first()

            if applicant_default_group:
                reverse_friend = db.query(Friend).filter(
                Friend.user_id == apply.applicant_id,
                Friend.friend_id == current_user.id
                ).first()
                if reverse_friend:
                  reverse_friend.status = 1
                  reverse_friend.friend_group_id = applicant_default_group.id
                # 可选：reverse_friend.remark = ""  # 视业务需求
                else:
                  db.add(Friend(
                    user_id=apply.applicant_id,
                    friend_id=current_user.id,
                    friend_group_id=applicant_default_group.id,
                    status=1
                  ))

            apply.status = 1
            db.commit()
        except Exception as e:
            db.rollback()
            logger.error(f"添加好友失败: {str(e)}")
            raise HTTPException(500, "系统处理失败")

        # 返回更新后的分组数据
        friends = db.query(Friend).filter(
            Friend.friend_group_id == group.id,
            Friend.status == 1
        ).options(joinedload(Friend.friend)).all()

        # 构建返回数据
        response_data = {
            "id": group.group.id,
            "name": group.group.name,
            "fixed": 1 if group.group.is_default else 0,
            "friends": [
                {
                    "id": f.id,
                    "remark": f.remark,
                    "userId": f.friend.id,
                    "nickname": f.friend.nickname,
                    "avatar": f.friend.avatar,
                    "sex": f.friend.sex,
                    "online": 1 if f.friend.online else 0,
                    "email": f.friend.email,
                    "lastAt": f.friend.last_at.strftime("%Y-%m-%d %H:%M:%S") if f.friend.last_at else None,
                    "createdAt": f.friend.created_at.strftime("%Y-%m-%d %H:%M:%S")
                } for f in friends
            ]
        }
        
        # 通过WebSocket通知申请者已通过好友申请
        try:
            from app.api.ws import ws_handler
            
            if apply.applicant_id in ws_handler.active_connections:
                # 构建通知消息
                notification = {
                    "type": 4,  # 通过好友申请
                    "body": {
                        # 原有分组数据
                        **response_data,
                        # 添加接受者信息，便于前端正确显示
                        "accepter": {
                            "id": current_user.id,
                            "nickname": current_user.nickname,
                            "avatar": current_user.avatar,
                            "userId": current_user.id  # 保持与前端一致的字段名
                        }
                    }
                }
                
                # 添加日志，记录通知消息内容
                logger.info(f"发送好友申请通过通知: applicant_id={apply.applicant_id}, current_user={current_user.id}, current_user_nickname={current_user.nickname}")
                logger.info(f"好友列表内容: {[{'id': f.id, 'nickname': f.friend.nickname, 'userId': f.friend.id} for f in friends]}")
                
                await ws_handler.send_message(apply.applicant_id, notification)
        except Exception as e:
            # 记录错误但不中断流程
            logger.error(f"WebSocket通知好友申请通过失败: {str(e)}")

        return {
            "code": 0,
            "message": "成功！",
            "data": response_data
        }
    else:  # 拒绝申请
        apply.status = 2
        db.commit()
        
        # 通过WebSocket通知申请者已拒绝好友申请
        try:
            from app.api.ws import ws_handler
            
            if apply.applicant_id in ws_handler.active_connections:
                # 构建通知消息
                notification = {
                    "type": 5,  # 拒绝好友申请
                    "body": {
                        "id": apply.id,
                        "userId": current_user.id,
                        "nickname": current_user.nickname
                    }
                }
                await ws_handler.send_message(apply.applicant_id, notification)
        except Exception as e:
            # 记录错误但不中断流程
            logger.error(f"WebSocket通知好友申请拒绝失败: {str(e)}")
            
        return {"code": 0, "message": "已拒绝申请", "data": None}


@router.get("/apply/page", tags=["申请管理"])
async def get_apply_page(
        lastId: Optional[str] = Query(default=None),
        size: int = Query(default=10, ge=1, le=100),
        db: Session = Depends(get_db),
        current_user: User = Depends(get_current_user)
):
    """
    分页获取申请列表
    修复空字符串参数问题
    """
    try:
        # 安全转换 lastId
        last_id = None
        if lastId and lastId.strip():  # 只有当 lastId 不为空且不全是空白字符时才转换
            try:
                last_id = int(lastId)
            except ValueError:
                return {
                    "code": 400,
                    "message": "lastId 参数格式错误，应为整数或空值",
                    "data": [],
                    "total": 0
                }

        # 构建基础查询
        base_query = db.query(Apply).filter(
            ((Apply.applicant_id == current_user.id) | (Apply.target_id == current_user.id)),
            Apply.type == 0,
            Apply.applicant_id != Apply.target_id  # 过滤掉自己申请自己的记录
        ).order_by(Apply.id.desc())

        # 应用游标分页
        if last_id is not None:
            base_query = base_query.filter(Apply.id < last_id)

        # 执行查询
        records = base_query.options(
            joinedload(Apply.applicant),
            joinedload(Apply.target)
        ).limit(size).all()

        # 格式化响应
        data = []
        for r in records:
            # 获取申请者和目标用户的信息
            applicant = r.applicant
            target = r.target
            
            # 构建用户信息
            def build_user_info(user):
                if not user:
                    return {
                        "id": None,
                        "userid": None,
                        "nickname": "已删除用户",
                        "avatar": "",
                        "sex": 0,
                        "online": 0,
                        "email": None,
                        "lastAt": None,
                        "createdAt": None
                    }
                return {
                    "id": user.id,
                    "userid": user.userid,
                    "nickname": user.nickname,
                    "avatar": user.avatar or "",
                    "sex": user.sex or 0,
                    "online": 1 if user.online else 0,
                    "email": user.email,
                    "lastAt": user.last_at.strftime("%Y-%m-%d %H:%M:%S") if user.last_at else None,
                    "createdAt": user.created_at.strftime("%Y-%m-%d %H:%M:%S") if user.created_at else None
                }

            # 获取申请者和目标用户信息
            user_info = build_user_info(applicant)
            target_info = build_user_info(target)
            
            data.append({
                "id": r.id,
                "applicantId": r.applicant_id,
                "applicantName": applicant.nickname if applicant else "已删除用户",
                "targetId": r.target_id,
                "targetName": target.nickname if target else "已删除用户",
                "content": r.content or "",
                "status": r.status,
                "createdAt": r.created_at.strftime("%Y-%m-%d %H:%M:%S"),
                "online": user_info["online"],
                "user": user_info,
                "targetUser": target_info
            })

        return {
            "code": 0,
            "message": "成功！",
            "data": data,
            "total": len(data)
        }

    except Exception as e:
        logger.error(f"分页查询失败: {str(e)}")
        return {
            "code": 500,
            "message": "服务器繁忙，请稍后重试",
            "data": [],
            "total": 0
        }


@router.get("/apply/audit/count", tags=["申请管理"])
async def audit_count(
        db: Session = Depends(get_db),
        current_user: User = Depends(get_current_user)
):
    """获取待审核申请数量"""
    try:
        count = db.query(Apply).filter(
            Apply.target_id == current_user.id,
            Apply.status == 0,
            Apply.type == 0
        ).count()
        return {"code": 0, "message": "成功！", "data": count}
    except Exception as e:
        logger.error(f"获取待审核数量失败: {str(e)}")
        return {"code": 500, "message": "获取待审核数量失败", "data": 0}


# ------------------------- 好友管理接口 -------------------------
@router.post("/friend/delete", tags=["好友管理"])
async def delete_friend(
        data: dict = Body(..., example={"userId": 123}),
        db: Session = Depends(get_db),
        current_user: User = Depends(get_current_user)
):
    """删除好友（逻辑删除）"""
    if "userId" not in data:
        raise HTTPException(status_code=400, detail="缺少必要的参数'userId'")

    try:
        # 删除双向好友关系
        # 查找当前用户的好友关系
        friend_rel = db.query(Friend).filter(
            Friend.user_id == current_user.id,
            Friend.friend_id == data["userId"],
            Friend.status == 1
        ).first()

        if not friend_rel:
            return {"code": 404, "message": "好友关系不存在", "data": None}

        # 删除当前用户的好友关系
        friend_rel.status = 3
        reverse_rel = db.query(Friend).filter(
            Friend.user_id == data["userId"],
            Friend.friend_id == current_user.id,
            Friend.status == 1
        ).first()

        if reverse_rel:
            reverse_rel.status = 3
        try:
            db.commit()
            
            # 通过WebSocket通知被删除的好友
            try:
                from app.api.ws import ws_handler
                
                if data["userId"] in ws_handler.active_connections:
                    # 构建通知消息
                    notification = {
                        "type": 6,  # 删除好友
                        "body": {
                            "userId": current_user.id,
                            "nickname": current_user.nickname
                        }
                    }
                    await ws_handler.send_message(data["userId"], notification)
            except Exception as e:
                # 记录错误但不中断流程
                logger.error(f"WebSocket通知好友删除失败: {str(e)}")
                
            return {"code": 0, "message": "删除成功", "data": None}
        except Exception as e:
            db.rollback()
            logger.error(f"删除好友失败，数据库提交错误: {str(e)}")
            raise HTTPException(status_code=500, detail="数据库操作失败")
    except Exception as e:
        raise HTTPException(status_code=500, detail="删除失败，请稍后重试")